﻿namespace Hardcodet.Wpf.TaskbarNotification
{
    using Hardcodet.Wpf.TaskbarNotification.Interop;
    using System;
    using System.Drawing;
    using System.Runtime.CompilerServices;
    using System.Windows;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Resources;

    internal static class Util
    {
        private static readonly bool isDesignMode = ((bool) DependencyPropertyDescriptor.FromProperty(DesignerProperties.IsInDesignModeProperty, typeof(FrameworkElement)).Metadata.DefaultValue);
        public static readonly object SyncRoot = new object();

        public static Window CreateHelperWindow()
        {
            return new Window { Width = 0.0, Height = 0.0, ShowInTaskbar = false, WindowStyle = WindowStyle.None, AllowsTransparency = true, Opacity = 0.0 };
        }

        public static void ExecuteIfEnabled(this ICommand command, object commandParameter, IInputElement target)
        {
            if (command != null)
            {
                RoutedCommand command2 = command as RoutedCommand;
                if (command2 != null)
                {
                    if (command2.CanExecute(commandParameter, target))
                    {
                        command2.Execute(commandParameter, target);
                    }
                }
                else if (command.CanExecute(commandParameter))
                {
                    command.Execute(commandParameter);
                }
            }
        }

        public static BalloonFlags GetBalloonFlag(this BalloonIcon icon)
        {
            switch (icon)
            {
                case BalloonIcon.None:
                    return BalloonFlags.None;

                case BalloonIcon.Info:
                    return BalloonFlags.Info;

                case BalloonIcon.Warning:
                    return BalloonFlags.Warning;

                case BalloonIcon.Error:
                    return BalloonFlags.Error;
            }
            throw new ArgumentOutOfRangeException("icon");
        }

        public static bool Is<T>(this T value, params T[] candidates)
        {
            if (candidates != null)
            {
                foreach (T local in candidates)
                {
                    if (value.Equals(local))
                    {
                        return true;
                    }
                }
            }
            return false;
        }

        public static bool IsDataContextDataBound(this FrameworkElement element)
        {
            if (element == null)
            {
                throw new ArgumentNullException("element");
            }
            return (element.GetBindingExpression(FrameworkElement.DataContextProperty) != null);
        }

        public static bool IsMatch(this MouseEvent me, PopupActivationMode activationMode)
        {
            switch (activationMode)
            {
                case PopupActivationMode.LeftClick:
                    return (me == MouseEvent.IconLeftMouseUp);

                case PopupActivationMode.RightClick:
                    return (me == MouseEvent.IconRightMouseUp);

                case PopupActivationMode.DoubleClick:
                    return me.Is<MouseEvent>(new MouseEvent[] { MouseEvent.IconDoubleClick });

                case PopupActivationMode.LeftOrRightClick:
                    return me.Is<MouseEvent>(new MouseEvent[] { MouseEvent.IconLeftMouseUp, MouseEvent.IconRightMouseUp });

                case PopupActivationMode.LeftOrDoubleClick:
                    return me.Is<MouseEvent>(new MouseEvent[] { MouseEvent.IconLeftMouseUp, MouseEvent.IconDoubleClick });

                case PopupActivationMode.MiddleClick:
                    return (me == MouseEvent.IconMiddleMouseUp);

                case PopupActivationMode.All:
                    return (me != MouseEvent.MouseMove);
            }
            throw new ArgumentOutOfRangeException("activationMode");
        }

        public static Icon ToIcon(this ImageSource imageSource)
        {
            if (imageSource == null)
            {
                return null;
            }
            Uri uriResource = new Uri(imageSource.ToString());
            StreamResourceInfo resourceStream = Application.GetResourceStream(uriResource);
            if (resourceStream == null)
            {
                string format = "The supplied image source '{0}' could not be resolved.";
                throw new ArgumentException(string.Format(format, imageSource));
            }
            return new Icon(resourceStream.Stream);
        }

        public static bool WriteIconData(ref NotifyIconData data, NotifyCommand command)
        {
            return WriteIconData(ref data, command, data.ValidMembers);
        }

        public static bool WriteIconData(ref NotifyIconData data, NotifyCommand command, IconDataMembers flags)
        {
            if (IsDesignMode)
            {
                return true;
            }
            data.ValidMembers = flags;
            lock (SyncRoot)
            {
                return WinApi.Shell_NotifyIcon(command, ref data);
            }
        }

        public static bool IsDesignMode
        {
            get
            {
                return isDesignMode;
            }
        }
    }
}

